﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ADONETDataServicesExtension.Utils;
using System.Data.Services;
using System.Collections;

namespace ADONETDataServicesExtension.Providers
{
    public class IDataServiceProvider : FrameworkEncapsulatedType<object>, IUpdatable, IExpandProvider
    {
        internal const string FrameworkTypeName = "System.Data.Services.Providers.IDataServiceProvider";

        public IDataServiceProvider(object iDataServiceProvider)
            : base(iDataServiceProvider)
        {
        }

        private IUpdatable FrameworkInternalIDataServiceProviderAsIUpdatable
        {
            get
            {
                return FrameworkObject as IUpdatable;
            }
        }

        public ResourceType GetResourceType(Type type)
        {
            return ReflectionHelper.Convert(ReflectionHelper.InvokeMethod(FrameworkTypeName, "GetResourceType", FrameworkObject, type), frameworkValue => new ResourceType(frameworkValue));
        }

        public IEnumerable ApplyExpansions(IQueryable queryable, ICollection<ExpandSegmentCollection> expandPaths)
        {
            return ((IExpandProvider)FrameworkObject).ApplyExpansions(queryable, expandPaths);
        }

        public bool NullPropagationRequired
        {
            get
            {
                return ReflectionHelper.GetProperty<bool>(FrameworkTypeName, "NullPropagationRequired", FrameworkObject);
            }
        }

        public ResourceProperty TryResolvePropertyName(Type type, string propertyName)
        {
            return ReflectionHelper.Convert(ReflectionHelper.InvokeMethod(FrameworkTypeName, "TryResolvePropertyName", FrameworkObject, type, propertyName), frameworkValue => new ResourceProperty(frameworkValue));
        }

        public bool GetTypeIsOrdered(Type type)
        {
            return ReflectionHelper.InvokeMethod<bool>(FrameworkTypeName, "GetTypeIsOrdered", FrameworkObject, type);
        }

        public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
        {
            FrameworkInternalIDataServiceProviderAsIUpdatable.AddReferenceToCollection(targetResource, propertyName, resourceToBeAdded);
        }

        public void ClearChanges()
        {
            FrameworkInternalIDataServiceProviderAsIUpdatable.ClearChanges();
        }

        public object CreateResource(string containerName, string fullTypeName)
        {
            return FrameworkInternalIDataServiceProviderAsIUpdatable.CreateResource(containerName, fullTypeName);
        }

        public void DeleteResource(object targetResource)
        {
            FrameworkInternalIDataServiceProviderAsIUpdatable.DeleteResource(targetResource);
        }

        public object GetResource(IQueryable query, string fullTypeName)
        {
            return FrameworkInternalIDataServiceProviderAsIUpdatable.GetResource(query, fullTypeName);
        }

        public object GetValue(object targetResource, string propertyName)
        {
            return FrameworkInternalIDataServiceProviderAsIUpdatable.GetValue(targetResource, propertyName);
        }

        public void RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved)
        {
            FrameworkInternalIDataServiceProviderAsIUpdatable.RemoveReferenceFromCollection(targetResource, propertyName, resourceToBeRemoved);
        }

        public object ResetResource(object resource)
        {
            return FrameworkInternalIDataServiceProviderAsIUpdatable.ResetResource(resource);
        }

        public object ResolveResource(object resource)
        {
            return FrameworkInternalIDataServiceProviderAsIUpdatable.ResolveResource(resource);
        }

        public void SaveChanges()
        {
            FrameworkInternalIDataServiceProviderAsIUpdatable.SaveChanges();
        }

        public void SetReference(object targetResource, string propertyName, object propertyValue)
        {
            FrameworkInternalIDataServiceProviderAsIUpdatable.SetReference(targetResource, propertyName, propertyValue);
        }

        public void SetValue(object targetResource, string propertyName, object propertyValue)
        {
            FrameworkInternalIDataServiceProviderAsIUpdatable.SetValue(targetResource, propertyName, propertyValue);
        }

        public ResourceType TryResolveTypeName(string name)
        {
            return ReflectionHelper.Convert(ReflectionHelper.InvokeMethod(FrameworkTypeName, "TryResolveTypeName", FrameworkObject, name), frameworkValue => new ResourceType(frameworkValue));
        }

        public ResourceContainer TryResolveContainerName(string name)
        {
            return ReflectionHelper.Convert(ReflectionHelper.InvokeMethod(FrameworkTypeName, "TryResolveContainerName", FrameworkObject, name), frameworkValue => new ResourceContainer(frameworkValue));
        }
    }
}